#!/usr/bin/env python3
"""
数据库诊断脚本
检查数据库中的数据情况，帮助排查为什么 Dashboard 没有数据
"""

import os
import sys
from pathlib import Path
from datetime import datetime, timedelta, timezone

from python.database.db_manager import DatabaseManager
from python.database.schema import ServiceMetric, Service, Endpoint, EndpointMetric, Trace, CollectionLog

# 添加父目录到 Python 路径
sys.path.insert(0, str(Path(__file__).parent.parent))

from dotenv import load_dotenv
from sqlalchemy import func

# 加载配置
env_path = Path(__file__).parent.parent / "config.env"
if env_path.exists():
    load_dotenv(env_path)

DATABASE_URL = os.getenv('DATABASE_URL', 'sqlite:///data/skywalking_data.db')

def main():
    print("=" * 80)
    print("SkyWalking 数据库诊断工具")
    print("=" * 80)
    print()
    
    # 初始化数据库管理器
    print(f"📊 数据库地址: {DATABASE_URL}")
    db_manager = DatabaseManager(DATABASE_URL, echo=False)
    
    with db_manager.get_session() as session:
        # 1. 检查服务数量
        print("\n" + "=" * 80)
        print("1️⃣  服务 (Services)")
        print("=" * 80)
        
        services = session.query(Service).all()
        print(f"总数: {len(services)}")
        
        if services:
            print("\n服务列表:")
            for s in services[:5]:  # 只显示前5个
                print(f"  - ID: {s.service_id}")
                print(f"    名称: {s.name}")
                print(f"    Layer: {s.layer}")
                print(f"    采集时间: {s.collected_at}")
                print()
            if len(services) > 5:
                print(f"  ... 还有 {len(services) - 5} 个服务")
        else:
            print("⚠️  没有服务数据！请检查：")
            print("   1. 采集服务是否正在运行？")
            print("   2. SkyWalking OAP 地址是否正确？")
            print("   3. 检查 logs/collector_service.log 查看错误信息")
        
        # 2. 检查服务指标
        print("\n" + "=" * 80)
        print("2️⃣  服务指标 (Service Metrics)")
        print("=" * 80)
        
        metrics_count = session.query(func.count(ServiceMetric.id)).scalar()
        print(f"总数: {metrics_count}")
        
        if metrics_count > 0:
            # 按指标类型统计
            metric_types = session.query(
                ServiceMetric.metric_name,
                func.count(ServiceMetric.id).label('count')
            ).group_by(ServiceMetric.metric_name).all()
            
            print("\n按类型统计:")
            for metric_name, count in metric_types:
                print(f"  - {metric_name}: {count} 条")
            
            # 最新的指标
            latest_metric = session.query(ServiceMetric).order_by(
                ServiceMetric.timestamp.desc()
            ).first()
            
            if latest_metric:
                print(f"\n最新指标时间: {latest_metric.timestamp} (UTC)")
                utc8_time = latest_metric.timestamp.replace(tzinfo=timezone.utc).astimezone(
                    timezone(timedelta(hours=8))
                )
                print(f"最新指标时间: {utc8_time.strftime('%Y-%m-%d %H:%M:%S')} (UTC+8)")
        else:
            print("⚠️  没有服务指标数据！")
        
        # 3. 检查端点
        print("\n" + "=" * 80)
        print("3️⃣  端点 (Endpoints)")
        print("=" * 80)
        
        endpoints_count = session.query(func.count(Endpoint.id)).scalar()
        print(f"总数: {endpoints_count}")
        
        if endpoints_count > 0:
            # 按服务统计
            endpoints_by_service = session.query(
                Service.name,
                func.count(Endpoint.id).label('count')
            ).join(Endpoint, Service.id == Endpoint.service_id
            ).group_by(Service.name).all()
            
            print("\n按服务统计:")
            for service_name, count in endpoints_by_service[:5]:
                print(f"  - {service_name}: {count} 个端点")
            if len(endpoints_by_service) > 5:
                print(f"  ... 还有 {len(endpoints_by_service) - 5} 个服务")
        else:
            print("⚠️  没有端点数据！")
        
        # 4. 检查端点指标
        print("\n" + "=" * 80)
        print("4️⃣  端点指标 (Endpoint Metrics)")
        print("=" * 80)
        
        endpoint_metrics_count = session.query(func.count(EndpointMetric.id)).scalar()
        print(f"总数: {endpoint_metrics_count}")
        
        if endpoint_metrics_count > 0:
            # 按指标类型统计
            endpoint_metric_types = session.query(
                EndpointMetric.metric_name,
                func.count(EndpointMetric.id).label('count')
            ).group_by(EndpointMetric.metric_name).all()
            
            print("\n按类型统计:")
            for metric_name, count in endpoint_metric_types:
                print(f"  - {metric_name}: {count} 条")
        else:
            print("⚠️  没有端点指标数据！")
        
        # 5. 检查 Trace
        print("\n" + "=" * 80)
        print("5️⃣  Trace")
        print("=" * 80)
        
        traces_count = session.query(func.count(Trace.id)).scalar()
        print(f"总数: {traces_count}")
        
        if traces_count > 0:
            # 成功/失败统计
            error_traces = session.query(func.count(Trace.id)).filter(
                Trace.is_error == True
            ).scalar()
            success_traces = traces_count - error_traces
            
            print(f"\n状态统计:")
            print(f"  - 成功: {success_traces}")
            print(f"  - 失败: {error_traces}")
            if traces_count > 0:
                print(f"  - 错误率: {(error_traces / traces_count * 100):.2f}%")
            
            # 时间范围
            first_trace = session.query(Trace).order_by(Trace.start_time).first()
            last_trace = session.query(Trace).order_by(Trace.start_time.desc()).first()
            
            if first_trace and last_trace:
                print(f"\n时间范围:")
                print(f"  - 最早: {first_trace.start_time} (UTC)")
                print(f"  - 最晚: {last_trace.start_time} (UTC)")
                
                first_utc8 = first_trace.start_time.replace(tzinfo=timezone.utc).astimezone(
                    timezone(timedelta(hours=8))
                )
                last_utc8 = last_trace.start_time.replace(tzinfo=timezone.utc).astimezone(
                    timezone(timedelta(hours=8))
                )
                print(f"  - 最早: {first_utc8.strftime('%Y-%m-%d %H:%M:%S')} (UTC+8)")
                print(f"  - 最晚: {last_utc8.strftime('%Y-%m-%d %H:%M:%S')} (UTC+8)")
        else:
            print("⚠️  没有 Trace 数据！")
        
        # 6. 检查采集日志
        print("\n" + "=" * 80)
        print("6️⃣  采集日志 (Collection Logs)")
        print("=" * 80)
        
        logs_count = session.query(func.count(CollectionLog.id)).scalar()
        print(f"总数: {logs_count}")
        
        if logs_count > 0:
            # 最近 5 条日志
            recent_logs = session.query(CollectionLog).order_by(
                CollectionLog.collected_at.desc()
            ).limit(5).all()
            
            print("\n最近 5 次采集:")
            for log in recent_logs:
                status_icon = "✅" if log.status == 'success' else "⚠️" if log.status == 'partial' else "❌"
                print(f"  {status_icon} {log.collected_at} (UTC)")
                utc8_time = log.collected_at.replace(tzinfo=timezone.utc).astimezone(
                    timezone(timedelta(hours=8))
                )
                print(f"     {utc8_time.strftime('%Y-%m-%d %H:%M:%S')} (UTC+8)")
                print(f"     状态: {log.status}")
                print(f"     服务: {log.services_collected}, 端点: {log.endpoints_collected}, "
                      f"Trace: {log.traces_collected}, 指标: {log.metrics_collected}")
                if log.message:
                    print(f"     消息: {log.message}")
                print()
        else:
            print("⚠️  没有采集日志！采集服务可能从未运行过。")
    
    # 7. 总结和建议
    print("\n" + "=" * 80)
    print("📝 诊断总结")
    print("=" * 80)
    
    if len(services) == 0:
        print("\n❌ 问题: 没有服务数据")
        print("\n解决方案:")
        print("  1. 启动采集服务:")
        print("     cd /Users/gaoyu/source_code/springboot-apm-demo/python")
        print("     nohup python3 collector_service.py > logs/collector_service.log 2>&1 &")
        print()
        print("  2. 检查采集日志:")
        print("     tail -f logs/collector_service.log")
    
    elif metrics_count == 0 or traces_count == 0:
        print("\n⚠️  问题: 有服务但缺少指标或 Trace 数据")
        print("\n可能原因:")
        print("  1. 采集服务刚启动，还在采集中")
        print("  2. SkyWalking 中这些服务没有实际流量")
        print("  3. 采集过程中出错")
        print("\n建议:")
        print("  1. 等待几分钟，让采集服务完成首次采集")
        print("  2. 检查日志: tail -f logs/collector_service.log")
        print("  3. 如果仍然没有数据，查看日志中的错误信息")
    
    else:
        print("\n✅ 数据库状态正常！")
        print(f"\n统计:")
        print(f"  - 服务: {len(services)}")
        print(f"  - 服务指标: {metrics_count}")
        print(f"  - 端点: {endpoints_count}")
        print(f"  - 端点指标: {endpoint_metrics_count}")
        print(f"  - Trace: {traces_count}")
        print(f"  - 采集日志: {logs_count}")
        print("\n现在可以访问 Streamlit Dashboard 查看数据可视化！")
    
    print("\n" + "=" * 80)


if __name__ == '__main__':
    main()

